package org.ecomap.android.app.fragments; import android.app.Activity; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.database.Cursor; import android.graphics.Color; import android.graphics.PorterDuff; import android.graphics.drawable.LayerDrawable; import android.location.Location; import android.os.AsyncTask; import android.os.Bundle; import android.support.design.widget.CoordinatorLayout; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; import android.support.v4.app.Fragment; import android.support.v4.app.FragmentManager; import android.support.v4.content.LocalBroadcastManager; import android.support.v7.app.AlertDialog; import android.text.TextUtils; import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.ImageView; import android.widget.RatingBar; import android.widget.ScrollView; import android.widget.TextView; import android.widget.Toast; import com.google.android.gms.maps.CameraUpdateFactory; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.maps.MapView; import com.google.android.gms.maps.MapsInitializer; import com.google.android.gms.maps.UiSettings; import com.google.android.gms.maps.model.CameraPosition; import com.google.android.gms.maps.model.LatLng; import org.ecomap.android.app.EcomapApplication; import org.ecomap.android.app.Problem; import org.ecomap.android.app.R; import org.ecomap.android.app.activities.CommentPhotoActivity; import org.ecomap.android.app.activities.MainActivity; import org.ecomap.android.app.data.EcoMapContract; import org.ecomap.android.app.data.model.ProblemPhotoEntry; import org.ecomap.android.app.sync.EcoMapAPIContract; import org.ecomap.android.app.sync.EcoMapService; import org.ecomap.android.app.tasks.GetPhotosTask; import org.ecomap.android.app.utils.ImageAdapter; import org.ecomap.android.app.utils.MapClustering; import org.ecomap.android.app.utils.NetworkAvailability; import org.ecomap.android.app.utils.SnackBarHelper; import org.ecomap.android.app.widget.EcoMapSlidingLayer; import org.ecomap.android.app.widget.ExpandableHeightGridView; import org.json.JSONObject; import java.net.HttpURLConnection; import java.net.URL; import java.util.ArrayList; import me.iwf.photopicker.PhotoPickerActivity; import me.iwf.photopicker.utils.PhotoPickerIntent; /** * A placeholder fragment containing a simple view. */ public class EcoMapFragment extends Fragment { private static final String tag = "EcoMapFragment"; private static int markerClickType; private static String filterCondition; public ImageAdapter imgAdapter; private Context mContext; private EcoMapReceiver receiver; private MapView mapView; private GoogleMap mMap; private ArrayList<Problem> values; public EcoMapSlidingLayer mSlidingLayer; private ImageView showTypeImage, showLike; private TextView showTitle, showByTime, showContent, showProposal, showNumOfLikes, showStatus; private ScrollView detailedScrollView; private static CameraPosition cameraPosition; private RatingBar problemRating; private Problem problemForSlidingLayer; private boolean problemLikedElsewhere; private static FloatingActionButton fabAddProblem; private static LatLng markerPosition = null; private static MapClustering mapClusterer; private CoordinatorLayout rootLayout; //for rotating screen - save last position of SlidingPanel public static boolean isOpenSlidingLayer = false; public static Problem lastOpenProblem; private static Snackbar addProblemSnackbar; private static boolean addproblemModeIsEnabled = false; private static final int REQUEST_CODE = 1; private static final int REQUEST_CODE_PHOTOS_ADDED = 2; private static ArrayList<String> selectedPhotos = new ArrayList<>(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i(tag, "onCreate"); setRetainInstance(true); } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { setRetainInstance(true); Log.i(tag, "onCreateView"); //getActivity().invalidateOptionsMenu(); View v = inflater.inflate(R.layout.map_layout_main, container, false); mapView = (MapView) v.findViewById(R.id.mapview); //Temporary is to initialize mapView by null to get rotation works without exceptions. mapView.onCreate(null); mMap = mapView.getMap(); mMap.setMyLocationEnabled(true); MapsInitializer.initialize(getActivity()); UiSettings UISettings = mMap.getUiSettings(); UISettings.setMapToolbarEnabled(false); UISettings.setMyLocationButtonEnabled(false); values = new ArrayList<>(); mContext = getActivity(); fabAddProblem = (FloatingActionButton) v.findViewById(R.id.fabAddProblem); rootLayout = (CoordinatorLayout) v.findViewById(R.id.rootLayout); FloatingActionButton fabUkraine = (FloatingActionButton) v.findViewById(R.id.fabUkraine); fabUkraine.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { mSlidingLayer.closeLayer(true); mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(50.461166, 30.417397), 5f)); } }); FloatingActionButton fabToMe = (FloatingActionButton) v.findViewById(R.id.fabToMe); fabToMe.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Location loc = mMap.getMyLocation(); if (loc != null) { mSlidingLayer.closeLayer(true); mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(loc.getLatitude(), loc.getLongitude()), 14.0f)); } } }); showTypeImage = (ImageView) v.findViewById(R.id.show_type_image); showLike = (ImageView) v.findViewById(R.id.show_like); showTitle = (TextView) v.findViewById(R.id.show_title); showByTime = (TextView) v.findViewById(R.id.show_date_added); showContent = (TextView) v.findViewById(R.id.show_content); showProposal = (TextView) v.findViewById(R.id.show_proposal); showNumOfLikes = (TextView) v.findViewById(R.id.show_numOfLikes); showStatus = (TextView) v.findViewById(R.id.show_status); detailedScrollView = (ScrollView) v.findViewById(R.id.details_scrollview); problemRating = (RatingBar) v.findViewById(R.id.problemRating); //deleteProblem = (ImageView) v.findViewById(R.id.action_delete_problem); mSlidingLayer = (EcoMapSlidingLayer) v.findViewById(R.id.show_problem_sliding_layer); MainActivity.slidingLayer = mSlidingLayer; mSlidingLayer.setOnInteractListener(new EcoMapSlidingLayer.OnInteractListener() { @Override public void onOpen() { //If onOpen, we show all lines of title showTitle.setMaxLines(5); showTitle.setEllipsize(TextUtils.TruncateAt.END); //set scroll UP detailedScrollView.fullScroll(View.FOCUS_UP);//if you move at the end of the scroll detailedScrollView.pageScroll(View.FOCUS_UP);//if you move at the middle of the scroll isOpenSlidingLayer = true; } @Override public void onShowPreview() { //If onPreview, we show only 1 line of title showTitle.setMaxLines(1); showTitle.setEllipsize(TextUtils.TruncateAt.END); isOpenSlidingLayer = true; } @Override public void onClose() { isOpenSlidingLayer = false; } @Override public void onOpened() { isOpenSlidingLayer = true; } @Override public void onPreviewShowed() { } @Override public void onClosed() { //isOpenSlidingLayer = false; getActivity().invalidateOptionsMenu(); } }); ExpandableHeightGridView gridview = (ExpandableHeightGridView) v.findViewById(R.id.gridview); gridview.setExpanded(true); imgAdapter = new ImageAdapter(mContext, new ArrayList<ProblemPhotoEntry>()); gridview.setAdapter(imgAdapter); final ScrollView mScrollView = detailedScrollView; mScrollView.post(new Runnable() { public void run() { mScrollView.scrollTo(0, 0); } }); Button addPhotoButton = (Button) v.findViewById(R.id.add_photo); addPhotoButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Send intent to library for picking photos if (MainActivity.isUserIdSet()) { PhotoPickerIntent intent = new PhotoPickerIntent(mContext); intent.setPhotoCount(8); intent.setShowCamera(true); startActivityForResult(intent, REQUEST_CODE); } else { signInAlertDialog(); } } }); return v; } @Override public void onResume() { super.onResume(); getActivity().setTitle(getString(R.string.item_map)); mapView.onResume(); getActivity().invalidateOptionsMenu(); IntentFilter filter = new IntentFilter("Data"); receiver = new EcoMapReceiver(); LocalBroadcastManager.getInstance(mContext).registerReceiver(receiver, filter); mapClusterer = new MapClustering(cameraPosition, mMap, mContext, this); setUpMap(); addProblemSnackbar = Snackbar.make(rootLayout, getString(R.string.choose_location), Snackbar.LENGTH_INDEFINITE); View snackBarView = addProblemSnackbar.getView(); snackBarView.setBackgroundColor(getResources().getColor(R.color.white)); TextView textView = (TextView) snackBarView.findViewById(android.support.design.R.id.snackbar_action); textView.setTextColor(Color.RED); addProblemSnackbar.setAction(getString(R.string.cancel), new View.OnClickListener() { @Override public void onClick(View v) { disableAddProblemMode(); } }); fabAddProblem.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (MainActivity.isUserIdSet()) { if (mapClusterer.getMarker() == null) { enableAddProblemMode(); } else { ((MainActivity) getActivity()).selectItem(MainActivity.NAV_ADD_PROBLEM); } } else { signInAlertDialog(); } } }); } // saving map position for restoring after rotation or backstack @Override public void onPause() { super.onPause(); cameraPosition = mMap.getCameraPosition(); // unregistering receiver after pausing fragment LocalBroadcastManager.getInstance(mContext).unregisterReceiver(receiver); mapClusterer = null; try { finalize(); } catch (Throwable throwable) { throwable.printStackTrace(); } //mSlidingLayer.closeLayer(true); } @Override public void onDestroy() { super.onDestroy(); Log.i(tag, "onDestroy"); mapView.onDestroy(); // if current map fragment is last in backstack - kill activity if (getFragmentManager().getBackStackEntryCount() == 0) { getActivity().finish(); } Log.i(tag, "mapView onDestroy"); } @Override public void onLowMemory() { super.onLowMemory(); mapView.onLowMemory(); } private class EcoMapReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { fillMap(filterCondition); } } private void setUpMap() { Log.i(tag, "set up map"); if (cameraPosition != null) { mMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); } if (new NetworkAvailability(getActivity().getSystemService(Context.CONNECTIVITY_SERVICE)) .isNetworkAvailable()) { //Start service to get a new number of revision and new data Intent intent = new Intent(this.getActivity(), EcoMapService.class); getActivity().startService(intent); } else { fillMap(filterCondition); } } //if there is some filter condition, then this method will be called. It will search only needed points private void fillMap(String filterCondition) { if (filterCondition == null) { filterCondition = ""; } if (cameraPosition != null) { mMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); } Log.i(tag, "fillmap with condition" + filterCondition); values.clear(); mMap.clear(); Cursor cursor = getActivity().getContentResolver() .query(EcoMapContract.ProblemsEntry.CONTENT_URI, null, filterCondition, null, null); if (cursor != null) { while (cursor.moveToNext()) { Problem p = new Problem(cursor, EcomapApplication.getAppContext()); values.add(p); } } if (cursor != null) { cursor.close(); } mapClusterer.updateEntryParameters(values); mapClusterer.setUpClusterer(); //for displaying marker and enableAddProblemMode() after screen rotation if (markerPosition != null || addproblemModeIsEnabled) { mapClusterer.addMarkerToMap(markerPosition); enableAddProblemMode(); } if (isOpenSlidingLayer) { mSlidingLayer.openPreview(true); fillSlidingPanel(lastOpenProblem); } } public static void setFilterCondition(String s) { filterCondition = s; Log.i(tag, "condition is set:" + filterCondition); } public static void setMarkerClickType(int type) { markerClickType = type; } public static int getMarkerClickType() { return markerClickType; } public static LatLng getMarkerPosition() { return markerPosition; } public static void setMarkerPosition(LatLng position) { markerPosition = position; } public void fillSlidingPanel(final Problem problem) { problemForSlidingLayer = problem; if (mMap.getCameraPosition().zoom < 13.0f) { mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(problemForSlidingLayer.getPosition(), 13.0f)); } cameraPosition = new CameraPosition(problemForSlidingLayer.getPosition(), 11.0f, 0.0f, 0.0f); //Set Problem object parameters to a view at show problem fragment showTypeImage.setImageResource(problemForSlidingLayer.getResBigImage()); showTitle.setText(problemForSlidingLayer.getTitle()); showByTime.setText(problemForSlidingLayer.getRelativeTime()); showContent.setText(problemForSlidingLayer.getContent()); showProposal.setText(problemForSlidingLayer.getProposal()); showNumOfLikes.setText(problemForSlidingLayer.getNumberOfLikes()); problemRating.setRating(Float.valueOf(problemForSlidingLayer.getSeverity())); LayerDrawable stars = (LayerDrawable) problemRating.getProgressDrawable(); stars.getDrawable(2).setColorFilter(Color.GRAY, PorterDuff.Mode.SRC_ATOP); if (problemForSlidingLayer.isLiked()) { showLike.setImageResource(R.drawable.heart_icon); } else { showLike.setImageResource(R.drawable.heart_empty); } //Check problem status and choose color fo text if (problemForSlidingLayer.getStatus().equalsIgnoreCase("UNSOLVED")) { showStatus.setText(getString(R.string.unsolved_problem)); showStatus.setTextColor(Color.RED); } else { showStatus.setText(getString(R.string.solved_problem)); showStatus.setTextColor(Color.GREEN); } //Mechanism for likes ++ when click on heart showLike.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { if (MainActivity.isUserIsAuthorized()) { if (!problemForSlidingLayer.isLiked()) { new AddVoteTask().execute(problemForSlidingLayer); } else if (problemForSlidingLayer.isLiked()) { //problem.setNumberOfLikes(-1); //problem.setLiked(false); Toast.makeText(mContext, mContext.getString(R.string.message_isAlreadyLiked), Toast.LENGTH_SHORT).show(); } showNumOfLikes.setText(problemForSlidingLayer.getNumberOfLikes()); } else { SnackBarHelper.showInfoSnackBar(getActivity(), getActivity().getWindow().getDecorView(), R.string.message_log_in_to_vote, Snackbar.LENGTH_SHORT); } } }); MainActivity.currentProblem = problemForSlidingLayer; cameraPosition = mMap.getCameraPosition(); getActivity().invalidateOptionsMenu(); // if (User.canUserDeleteProblem(problem)){ // deleteProblem.setVisibility(View.VISIBLE); // // deleteProblem.setOnClickListener(new View.OnClickListener() { // @Override // public void onClick(View v) { // final AlertDialog.Builder alert = new AlertDialog.Builder(getActivity()); // // cameraPosition = mMap.getCameraPosition(); // // alert.setMessage(getString(R.string.want_delete_problem)); // alert.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() { // @Override // public void onClick(DialogInterface dialog, int which) { // if (new NetworkAvailability(getActivity().getSystemService(Context.CONNECTIVITY_SERVICE)).isNetworkAvailable()) { // new DeleteTask(mContext).execute(String.valueOf(problem.getId())); // mSlidingLayer.closeLayer(true); // } // } // }); // // // alert.setNegativeButton(getString(R.string.no), new DialogInterface.OnClickListener() { // @Override // public void onClick(DialogInterface dialog, int which) { // // } // }); // alert.show(); // } // }); // } else { // deleteProblem.setVisibility(View.INVISIBLE); // } //comments FragmentManager chFm = getChildFragmentManager(); Fragment f; //if (f == null) { f = CommentsFragment.newInstance(problemForSlidingLayer); //} chFm.beginTransaction().replace(R.id.fragment_comments, f, CommentsFragment.LOG_TAG).commit(); //photos new GetPhotosTask(this).execute(problemForSlidingLayer.getId()); } private void signInAlertDialog() { AlertDialog.Builder alert = new AlertDialog.Builder(mContext); alert.setMessage(R.string.error_need_to_sign_in); alert.setPositiveButton(getString(R.string.sign_in), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { new LoginFragment().show(getFragmentManager(), "login_layout"); } }); alert.setNegativeButton(getString(R.string.cancel), new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { } }); alert.show(); } @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); //Getting photo paths from lib if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE) { if (data != null) { selectedPhotos.clear(); selectedPhotos = data.getStringArrayListExtra(PhotoPickerActivity.KEY_SELECTED_PHOTOS); if (selectedPhotos.size() > 0) { Intent intent = new Intent(mContext, CommentPhotoActivity.class); intent.putExtra("problem_id", lastOpenProblem.getId()); intent.putExtra("selectedPhotos", selectedPhotos); startActivityForResult(intent, REQUEST_CODE_PHOTOS_ADDED); } } } else if (resultCode == Activity.RESULT_OK && requestCode == REQUEST_CODE_PHOTOS_ADDED) { new GetPhotosTask(this).execute(lastOpenProblem.getId()); } } public static CameraPosition getCameraPosition() { return cameraPosition; } private void enableAddProblemMode() { addproblemModeIsEnabled = true; setMarkerClickType(2); addProblemSnackbar.show(); fabAddProblem.setImageResource(R.drawable.ic_done_white_24dp); } public static void disableAddProblemMode() { addproblemModeIsEnabled = false; setMarkerClickType(0); setMarkerPosition(null); if (mapClusterer != null) { mapClusterer.deleteMarker(); } addProblemSnackbar.dismiss(); fabAddProblem.setImageResource(R.drawable.ic_location_on_white_24dp); } public boolean isAddproblemModeIsEnabled() { return addproblemModeIsEnabled; } public static Problem getLastOpenProblem() { return lastOpenProblem; } public class AddVoteTask extends AsyncTask<Problem, Void, Boolean> { private final String LOG_TAG = AddVoteTask.class.getSimpleName(); private Integer problem_id; private Problem problem; @Override protected Boolean doInBackground(Problem... params) { URL url; Boolean result = Boolean.FALSE; problem = params[0]; problem_id = problem.getId(); //validation if (MainActivity.isUserIsAuthorized()) { if (params.length > 0 && params[0] != null) { HttpURLConnection connection = null; try { //creating JSONObject for request JSONObject request = new JSONObject(); request.put("content", params[0]); url = new URL(EcoMapAPIContract.ECOMAP_API_URL + "/problems/" + problem_id + "/vote"); connection = (HttpURLConnection) url.openConnection(); connection.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/json; charset=UTF-8"); connection.setDoOutput(true); connection.connect(); /** * sending request * request.toString() - translate our object into appropriate JSON text * { * "content": "your comment" * } */ //OutputStream outputStream = connection.getOutputStream(); //outputStream.write(request.toString().getBytes("UTF-8")); //handling result from server if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) { result = Boolean.TRUE; } else if (connection.getResponseCode() == HttpURLConnection.HTTP_BAD_REQUEST) { result = Boolean.FALSE; } } catch (Exception e) { Log.e(LOG_TAG, e.getMessage(), e); } finally { if (connection != null) { connection.disconnect(); } } } } problemLikedElsewhere = !(result); return result; } @Override public void onPostExecute(Boolean bool) { problemForSlidingLayer.setLiked(); if (problemLikedElsewhere) { Toast.makeText(mContext, mContext.getString(R.string.message_isAlreadyLiked), Toast.LENGTH_SHORT).show(); } else { Toast.makeText(mContext, mContext.getString(R.string.message_isLiked), Toast.LENGTH_SHORT).show(); problemForSlidingLayer.addLike(); showNumOfLikes.setText(problemForSlidingLayer.getNumberOfLikes()); } showLike.setImageResource(R.drawable.heart_icon); } } public static MapClustering getMapClusterer(){ return mapClusterer; } }